docs(WORKAROUND_CATALOG): add durable-snapshot + touch-refresh operational recipe (Closes #364) - #366
Conversation
…ional recipe under CC#62272 Closes #364. Adds a "Operational recipe: durable-snapshot + touch-refresh stack" subsection inside the existing CC#62272 entry. Documents what the `tool`-depth "out-of-band snapshot" row of that entry actually looks like when built and run for a week. Four-piece stack: sane cleanupPeriodDays, hourly rsync-with-hardlink, daily selective touch (`-mtime +20`), Persistent=true systemd-timers. Five non-obvious behaviors documented, each one caught on live data 2026-09-01 through 2026-09-05: - Blanket `find -exec touch` breaks `claude --continue`'s most-recent-modified-JSONL heuristic; selective `-mtime +20` preserves it. - `/rename <name>` writes both `~/.claude/sessions/<pid>.json` (runtime, dies with process, tracks formerNames[]) and `~/.claude/projects/<key>/<sid>/custom-title.json` (durable, what `--resume <name>` reads at invocation). - rsync `--link-dest` cannot cross filesystems; keep prev/new snapshots on the same filesystem or switch to `cp --reflink` on Btrfs. - `find -newer` on an rsync'd archive is not evidence of freshness — source mtime is preserved. Use content hashes for reconciliation. - Prune stale snapshots INSIDE the same cron, AFTER a successful snapshot pass — never before, or a failing pass will delete history. Restore workflow: `find`-for-orphaned-project-dirs, rsync-back additive, touch to lift restored files above the retention cliff, verify with `claude --resume <sid>` (bypasses the /resume picker). Fallback: subagent tree under `<sid>/subagents/` plus `~/.claude/history.jsonl` entries for the sessionId often survive when the main transcript doesn't — enough to reconstruct a session-continuation brief. Docs-only, not load-bearing. Extends the CC#62272 entry rather than adding a new top-level entry since it's the same bug's mitigation, just spelled out. Ref #218 (parent catalog).
There was a problem hiding this comment.
Review: PR #366 WORKAROUND_CATALOG durable snapshot recipe
Date: 2026-09-05
Reviewed: PR #366 (WORKAROUND_CATALOG.md) at head 713989ce053a28e2636b1a7efafa84d367570b0d
Round: 1
Label applied: changes-requested
What Is Correct
- [Read] The new subsection does not reintroduce the retracted signed-int32-overflow mechanism. The existing entry still says the int32 hypothesis was retracted and the mechanism is unresolved (
WORKAROUND_CATALOG.md:80-101), while the added recipe explicitly frames the snapshot mitigation as mechanism-independent (WORKAROUND_CATALOG.md:103-105). - [Read] The subagent fallback is coherent at the docs level. The daily
find ~/.claude/projects/ -type f -mtime +20 -exec touch {} +traversal reaches nested per-session trees, and the fallback explicitly names~/.claude/projects/<key>/<sid>/subagents/plus~/.claude/history.jsonlas reconstruction sources (WORKAROUND_CATALOG.md:111,WORKAROUND_CATALOG.md:129). - [Measured] I found no client/customer/project identifiers or origin secrets in the PR diff. Command:
gh pr diff 366 --repo cnighswonger/claude-code-cache-fix | rg -n '(/home/|visits-|vsits|client|customer|project name|[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+|ssh-rsa|BEGIN .*PRIVATE|api[_-]?key|token|secret)'exited 1 with no matches. - [Measured]
Closes #364targets the intended open issue.gh issue view 364 --repo cnighswonger/claude-code-cache-fix --json number,state,titlereports issue 364 asOPEN, titleddocs(WORKAROUND_CATALOG): add durable-snapshot + touch-refresh workaround stack for CC#41458 (session-JSONL loss). - [Measured] The upstream status references still match the catalog context:
gh issue view 62272 --repo anthropics/claude-code --json state,stateReason,closedAtreportsCLOSED,DUPLICATE,2026-08-19T20:52:54Z;gh issue view 41458 --repo anthropics/claude-code --json statereportsOPEN.
Blockers
- [Read] The restore command omits the
projects/path component from the archive side, so it does not match the snapshot shape documented four lines earlier. The stack says the hourly job snapshots all of~/.claude/to<archive>/snap-*(WORKAROUND_CATALOG.md:110), which means project directories would restore from something like<archive>/snap-<ts>/projects/<project-key>/. The restore step instead saysrsync -a <archive>/snap-<pre-loss-timestamp>/-home-manager-... ~/.claude/projects/-home-manager-.../(WORKAROUND_CATALOG.md:125). That command only works if the archive root is already~/.claude/projects/, contradicting the "not justprojects/" invariant. Fix the example to includeprojects/<project-key>/on the source side, or explicitly document that<archive>points at the snapshot'sprojects/subdirectory.
What Needs Attention
- [Measured] CI was not green at review time.
gh pr view 366 --repo cnighswonger/claude-code-cache-fix --json statusCheckRollupshowed Node 18, 20, and 22 test jobsIN_PROGRESS; GitGuardian and Snyk wereSUCCESS. This PR is docs-only, so I did not runuv run pytest -q.
Bloat / Non-Functional
- [Measured] Proportionate. The PR touches only
WORKAROUND_CATALOG.mdwith 28 additions and 0 deletions:gh pr diff 366 --repo cnighswonger/claude-code-cache-fix | awk ...reportedadditions=28 deletions=0.
Recommendations
- Replace the restore command with a placeholder form that preserves the documented whole-
~/.claude/archive layout, for examplersync -a <archive>/snap-<pre-loss-timestamp>/projects/<project-key>/ ~/.claude/projects/<project-key>/. - Keep the mechanism-independent wording as-is; it correctly avoids reviving the PR #359 int32-overflow framing.
Bottom Line
Request changes. The new workaround section is directionally sound and avoids the retracted mechanism claim, but the restore command is load-bearing for the documented operational recipe and currently points at the wrong archive path for the snapshot shape the PR recommends.
— Codex, cross-LLM review, round 1
The archive is documented as snapshotting whole ~/.claude/, so the archive
layout has projects/, file-history/, etc. as subdirs of snap-<ts>/. The R1
restore command wrote the source path as
<archive>/snap-<ts>/-home-manager-...
which skipped the projects/ component and would have missed the file at
restore time.
Fix: include projects/ in the source path. Also extends the invocation with
a sibling example for file-history/ so the "restore other subtrees the same
way" path is spelled out, matching the WSL2-blast-radius point earlier in
the entry.
Addresses Codex R1 blocker on #366.
There was a problem hiding this comment.
Cross-LLM Review: PR #366 round 2 (Grok, substitute for Codex)
Note: Codex GPT account quota exhausted at review time. Grok (xAI) substituted per operator directive; per that directive Grok's verdict uses the Codex label set (approved-by-codex-agent / reviewed-by-codex-agent).
Head: b6502da
Round: 2
What Is Correct
- R2 one-line restore fix now reads
rsync -a ARCHIVE/snap-TS/projects/-home-manager-.../ ~/.claude/projects/-home-manager-.../; this exactly matches the whole-~/.claude/ snapshot shape described in the preceding paragraph (snapshot root containsprojects/,file-history/, etc.). - Sibling example
rsync -a ARCHIVE/snap-TS/file-history/ ~/.claude/file-history/uses identicalARCHIVE/snap-TS/SUBTREE/shape, internally consistent. - Diff [Read] shows only the corrected command + example; no client-id strings, no "Closes #364", no re-introduction of int32-overflow framing that was retracted in PR #359.
Blockers
- None. R1 blocker (missing
projects/component) is cleanly resolved by the single-line change.
What Needs Attention
- None observed in the added subsection.
Bloat
- None; the new "Operational recipe" subsection is scoped to the CC#62272 entry and adds only the minimal restore workflow required to make the mitigation actionable.
Recommendations
- Would confirm via
git show --stat b6502dathat only the documented subsection and the round-1 artifact were touched (no code paths).
Bottom Line
APPROVE
— Grok, cross-LLM review, round 2
There was a problem hiding this comment.
Cross-LLM Review: PR #366 round 2 (Grok, Codex substitute)
Note: Codex GPT account quota exhausted at review time. Grok (xAI) substituted per operator directive; posting under codex-reviewer identity so the cross-LLM audit trail is stable regardless of the underlying model that produced the verdict.
Head: b6502da
Round: 2
What Is Correct
- R2 one-line restore fix now reads
rsync -a ARCHIVE/snap-TS/projects/-home-manager-.../ ~/.claude/projects/-home-manager-.../; this exactly matches the whole-~/.claude/ snapshot shape described in the preceding paragraph (snapshot root containsprojects/,file-history/, etc.). - Sibling example
rsync -a ARCHIVE/snap-TS/file-history/ ~/.claude/file-history/uses identicalARCHIVE/snap-TS/SUBTREE/shape, internally consistent. - Diff [Read] shows only the corrected command + example; no client-id strings, no "Closes #364", no re-introduction of int32-overflow framing that was retracted in PR #359.
Blockers
- None. R1 blocker (missing
projects/component) is cleanly resolved by the single-line change.
What Needs Attention
- None observed in the added subsection.
Bloat
- None; the new "Operational recipe" subsection is scoped to the CC#62272 entry and adds only the minimal restore workflow required to make the mitigation actionable.
Recommendations
- Would confirm via
git show --stat b6502dathat only the documented subsection and the round-1 artifact were touched (no code paths).
Bottom Line
APPROVE
— Grok, cross-LLM review, round 2
Summary
Closes #364. Adds an "Operational recipe: durable-snapshot + touch-refresh stack" subsection inside the existing CC#62272 entry in
WORKAROUND_CATALOG.md. Documents what thetool-depth "out-of-band snapshot" row of that entry actually looks like when built and run for a week.Follows the plan approved on #364 by @cnighswonger (2026-09-05T15:23Z).
What lands
cleanupPeriodDays, hourlyrsync -a --link-dest, daily selectivefind -mtime +20 -exec touch,Persistent=truesystemd-timers.--continue's mtime heuristic./renamewrites to two files (sessions/<pid>.jsonruntime +custom-title.jsondurable).--link-destcan't cross filesystems.find -neweron rsync'd archive is not evidence of freshness.Non-Functional Requirements
Test plan
Closes #364
Ref #218
🤖 Generated with Claude Code